package com.igeek.web;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.igeek.domain.*;
import com.igeek.service.*;
import com.igeek.utils.Result;
import lombok.AllArgsConstructor;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author spike
 * @since 2022-01-12
 */
@RestController
@Slf4j
public class ProductController {
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductimageService productimageService;
    @Autowired
    private ReviewService reviewService;
    @Autowired
    private PropertyvalueService propertyvalueService;
    @Autowired
    private OrderitemService orderitemService;
    @Resource
    private ElasticsearchRestTemplate template;
    //批量导入数据到es中
    @GetMapping("/bulkProduct")
    public String bulkProduct(){
        //1.创建索引
        IndexOperations indexOperations = template.indexOps(Product.class);
        if(exists(indexOperations)){
            delete(indexOperations);
        }
        create(indexOperations);
        //2.导入数据
        List<Product> products = productService.list();
        template.save(products);
        return "success";
    }

    boolean exists(IndexOperations indexOperations) {
        boolean exists = indexOperations.exists();
        System.out.println("索引是否存在：" + exists);
        return exists;
    }

    void delete(IndexOperations indexOperations) {
        boolean delete = indexOperations.delete();
        System.out.println("索引是否删除：" + delete);
    }

    void create(IndexOperations indexOperations) {
        boolean flag = indexOperations.create();
        System.out.println("索引创建结果：" + flag);
    }
    //从es中搜索数据
    // foresearch  var url = this.uri + "?keyword=" + keyword;
    @PostMapping("/foresearch")
    public List<Product> foresearchFromES(String keyword)  {
        //定义query查询
        MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyword,
                "name", "subTitle");
        HighlightBuilder highlightBuilder = new HighlightBuilder(); // 生成高亮查询器
        highlightBuilder.field("name");// 高亮查询字段
        highlightBuilder.field("subTitle");// 高亮查询字段
        highlightBuilder.requireFieldMatch(false); // 如果要多个字段高亮,这项要为false
        highlightBuilder.preTags("<span style='color:red'>"); // 高亮设置
        highlightBuilder.postTags("</span>");
        highlightBuilder.fragmentSize(800000); // 最大高亮分片数
        highlightBuilder.numOfFragments(0); // 从第一个分片获取高亮片段
//        Pageable pageable = PageRequest.of(1, 10); // 设置分页参数
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder) // match查询
//                .withPageable(pageable)
                .withHighlightBuilder(highlightBuilder) // 设置高亮
                .build();
        SearchHits<Product> searchHits = template.search(searchQuery, Product.class);
        List<Product> products = new ArrayList();
        for (SearchHit<Product> searchHit : searchHits) { // 获取搜索到的数据
            Product content = searchHit.getContent();
            // 处理高亮
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            for (Map.Entry<String, List<String>> stringHighlightFieldEntry : highlightFields.entrySet()) {
                String key = stringHighlightFieldEntry.getKey();
                if (StringUtils.equals(key, "name")) {
                    List<String> fragments = stringHighlightFieldEntry.getValue();
                    StringBuilder sb = new StringBuilder();
                    for (String fragment : fragments) {
                        sb.append(fragment.toString());
                    }
                    content.setName(sb.toString());
                }
                if (StringUtils.equals(key, "subTitle")) {
                    List<String> fragments = stringHighlightFieldEntry.getValue();
                    StringBuilder sb = new StringBuilder();
                    for (String fragment : fragments) {
                        sb.append(fragment.toString());
                    }
                    content.setSubTitle(sb.toString());
                }
            }
            products.add(content);
        }
//        Page page = new PageImpl(list, pageable, searchHits.getTotalHits());
//        list.forEach(System.out::println);

        //填充第一张图片
        productimageService.fillFirstImage(products);

        for (Product product : products) {
            //填充销量
            orderitemService.setSalCount(product);
            //填充评价
            reviewService.setReviewsAndCount(product);
        }

        return products;
    }




    public List<Product> foresearchFromDB(String keyword){
        QueryWrapper<Product> wrapper = new QueryWrapper<>();
        wrapper.like("name",keyword).or().like("subTitle",keyword);
        List<Product> products = productService.list(wrapper);
        //填充第一张图片
        productimageService.fillFirstImage(products);

        for (Product product : products) {
            //填充销量
            orderitemService.setSalCount(product);
            //填充评价
            reviewService.setReviewsAndCount(product);
        }

        return products;
    }

    //http://localhost:8080/foreproduct/958
    //根据id获取产品
    @GetMapping("/foreproduct/{pid}")
    public Result getProductById(@PathVariable("pid") Integer pid){
        Product product = productService.getById(pid);
        //设置产品对应的分类
        product.setCategory(new Category(product.getCid()));
        //设置第一张图片
        product.setFirstProductImage(productimageService.getPImgByPid(product.getId()));
       //设置缩略图
        productimageService.setSingleImg(product);
        //设置详情图
        productimageService.setDetailImg(product);
        /*设置评价和评价总数*/
        reviewService.setReviewsAndCount(product);
        /*设置评价用户*/
        reviewService.setReviewUser(product);
        /*设置产品属性*/
        propertyvalueService.setPv(product);
        /*设置销量*/
        orderitemService.setSalCount(product);
        return Result.success(product);
    }
    //categories/" + cid + "/" + this.uri + "?start=" + start;
    @GetMapping("/categories/{cid}/products")
    public PageInfo<Product> productList(@PathVariable("cid") Integer cid,
                                         @RequestParam(value = "start",required = true,defaultValue = "1") Integer start,
                                         @RequestParam(value = "size",required = true,defaultValue = "5") Integer size){
        PageHelper.startPage(start,size);
        QueryWrapper<Product> wrapper = new QueryWrapper<>();
        wrapper.eq("cid",cid);
        List<Product> productList = productService.list(wrapper);
        for(int i=0;i<productList.size();i++){
            productList.get(i).setFirstProductImage(productimageService.getPImgByPid(productList.get(i).getId()));
        }
        PageInfo<Product> pageInfo = new PageInfo<>(productList);
        //找出Product对应的Productimage的一条数据
        log.info("pageInfo1:"+pageInfo);
        return pageInfo;

    }
}

